package com.talkweb.securitycamera.utils.eventlib.communicationevent;

import com.talkweb.securitycamera.utils.eventlib.communicationevent.dispatch.BackgroudDispatch;
import com.talkweb.securitycamera.utils.eventlib.communicationevent.dispatch.MainDispatch;
import com.talkweb.securitycamera.utils.eventlib.communicationevent.dispatch.ThreadModel;
import ohos.agp.utils.TextTool;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

/**
 * @version 1.0.1
 * @description: 图库通信事件管理器
 * @program: Gallery
 * @Author xiaozhijun
 * @Date 2020/12/23 9:47
 */
public class PhotoEventManager {

    private static final String TAG = "PhotoEventManager";

    private static class EbentManagerHolder {
        public static PhotoEventManager instance = new PhotoEventManager();
    }

    private PhotoEventManager() {
        mainDispatch = new MainDispatch();
        backgroudDisptach = new BackgroudDispatch();
    }

    public static PhotoEventManager getInstance() {
        return EbentManagerHolder.instance;
    }

    //监听器列表
    private final HashMap<String, Object> listenMap = new HashMap<>();

    private MainDispatch mainDispatch;

    private BackgroudDispatch backgroudDisptach;

    //同步锁
    private final Object lock = new Object();

    /**
     * 注册单个监听器
     *
     * @param listener 监听器对象
     * @param topic    监听主题
     */
    public void registerEvent(IEventListener listener, String topic) {


        if (topic == null || topic.equals("")) {
            return;
        }
        synchronized (lock) {
            Object obj = listenMap.get(topic);
            if (null == obj) {
                // 还没有监听器，直接放到Map集合
                listenMap.put(topic, listener);
            } else if (obj instanceof IEventListener) {
                //只有一个监听器
                IEventListener oldListener = (IEventListener) obj;
                if (listener == oldListener) {
                    return;
                }
                LinkedList<IEventListener> list = new LinkedList<>();
                list.add(oldListener);
                list.add(listener);
                listenMap.put(topic, list);
            } else if (obj instanceof List) {
                // 有多个监听器
                LinkedList<IEventListener> listeners = (LinkedList<IEventListener>) obj;
                if (listeners.indexOf(listener) >= 0) {
                    return;
                }
                listeners.add(listener);
            }
        }

    }

    /**
     * 注册多个个监听器
     *
     * @param listener 监听器对象
     * @param topics   监听主题数组
     */
    public void registerEvent(IEventListener listener, String[] topics) {
        if (topics != null) {
            for (String topic : topics) {
                registerEvent(listener, topic);
            }
        }
    }

    /**
     * 注销单个监听器
     *
     * @param listener 监听器对象
     * @param topic    监听主题
     */
    public void unRegisterEvent(IEventListener listener, String topic) {
        if (topic == null || topic.equals("")) {
            return;
        }
        synchronized (lock) {
            Object obj = listenMap.get(topic);
            if (null == obj) {
                return;
            } else if (obj instanceof IEventListener) {
                // 有一个监听器
                if (obj == listener) {
                    listenMap.remove(topic);
                }
            } else if (obj instanceof List) {
                // 有多个监听器
                LinkedList<IEventListener> listeners = (LinkedList<IEventListener>) obj;
                listeners.remove(listener);
            }
        }
    }


    /**
     * 注销单个监听器
     *
     * @param listener 监听器对象
     * @param topics   监听主题数组
     */
    public void unRegisterEvent(IEventListener listener, String[] topics) {
        if (topics != null) {
            for (String topic : topics) {
                unRegisterEvent(listener, topic);
            }
        }
    }


    /**
     * 指定线程发送事件
     *
     * @param event
     * @param model
     */
    public void post(PhotoEvent event, ThreadModel model) {
        switch (model) {
            case MAIN:
                //主线程
                mainDispatch.post(event);
                break;
            case BACKGROUND:
                //新建后台线程执行
                backgroudDisptach.post(event);
                break;
            default:
                post(event);
                break;
        }
    }

    /**
     * 发送事件（默认在当前线程执行）
     *
     * @param event 事件
     */
    public void post(PhotoEvent event) {
        if (listenMap.size() == 0) {
            return;
        }
        if (null != event && !TextTool.isNullOrEmpty(event.getTopic())) {
            String topic = event.getTopic();
            // 通知事件监听器处理事件
            IEventListener listener = null;
            LinkedList<IEventListener> listeners = null;

            synchronized (lock) {
                Object obj = listenMap.get(topic);
                if (obj == null) {
                    return;
                }
                if (obj instanceof IEventListener) {
                    listener = (IEventListener) obj;
                } else if (obj instanceof LinkedList) {
                    listeners = (LinkedList<IEventListener>) ((LinkedList) obj).clone();
                }
            }

            // 分发事件
            if (null != listener) {
                listener.onEvent(event);
            } else if (null != listeners && listeners.size() > 0) {
                for (IEventListener l : listeners) {
                    l.onEvent(event);
                }
            }
            // 把对象放回池里面
            event.recycle();
        }
    }

}
